﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;

namespace YmtAuth.Domain.Repository
{
    public interface IRepository_v1<TEntity, TKey>
        where TEntity : IEntity<TKey>
    //where TKey : IComparable<TKey>, IEquatable<TKey>
    {
        #region [ 不指定数据库，表 ]
        TEntity FindById(TKey id);
        TEntity FindOne(Expression<Func<TEntity, bool>> exp);
        TEntity FindAndModify(IMongoQuery query, IMongoUpdate update);
        IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> exp);
        IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> exp, int index, int limit);
        IQueryable<TEntity> FindAll(string dbName, string collectionName, int index, int limit);
        IQueryable<TEntity> Find<TSortKey>(Expression<Func<TEntity, bool>> exp, Expression<Func<TEntity, TSortKey>> orderExp, System.Data.SqlClient.SortOrder order, int index, int limit);
        void Add(TEntity entity);
        void Save(TEntity entity, WriteConcern w);
        void Save(TEntity entity);
        void Save(TEntity entity, string dbName, string collectionName);
        void AddRang(IEnumerable<TEntity> entity);
        void Remove(TKey id);       
        bool Exists(Expression<Func<TEntity, bool>> exp);
        long Count(Expression<Func<TEntity, bool>> exp);
        #region [基于Query 查询]
        TEntity FindOne(IMongoQuery query, bool isSingleOrDefault = false);
        TEntity FindOne(IMongoQuery query,string dbName,string tbName, bool isSingleOrDefault = false);
        IQueryable<TEntity> Find(IMongoQuery query);
        IQueryable<TEntity> Find(IMongoQuery query, string dbName, string tbName);
        IQueryable<TEntity> Find(IMongoQuery query, IMongoFields fields);
        IQueryable<TEntity> Find(IMongoQuery query, IMongoFields fields, int index, int limit);
        IQueryable<TEntity> Find<TSortKey>(IMongoQuery query, IMongoSortBy sort, IMongoFields fields, int index, int limit);
        bool Remove(IMongoQuery query);
        bool Exists(IMongoQuery query);
        long Count(IMongoQuery query);
        void Update(IMongoQuery query, IMongoUpdate update);
        void UpdateMulti(IMongoQuery query, IMongoUpdate update);
        void Update(IMongoQuery query, IMongoUpdate update, WriteConcern w);
        #endregion
       
        #endregion
        #region [Async]

        Task AddAsync(TEntity entity, Action<AggregateException> errHandle = null
            , CancellationToken token = default(CancellationToken));
        Task AddAsync(TEntity entity, string dbName, string collectionName,
            Action<AggregateException> errHandle = null, CancellationToken token = default(CancellationToken));
        Task<DeleteResult> RemoveAsync(FilterDefinition<TEntity> queryfilter,
            CancellationToken token = default(CancellationToken));
        #endregion
        #region [ 指定数据库，表 ]
        TEntity FindById(TKey id, string dbName, string collectionName);
        TEntity FindOne(Expression<Func<TEntity, bool>> exp, string dbName, string collectionName);
        TEntity FindOne(IMongoQuery query, string dbName, string collectionName);
        void Save(TEntity entity, WriteConcern w, string dbName, string collectionName);
        TEntity FindOneByPrimaryPreferred(IMongoQuery query, string dbName, string tbName,
            bool isSingleOrDefault = false);
        IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> exp, string dbName, string collectionName);
       
        void Add(TEntity entity, string dbName, string collectionName);
        void AddRang(IEnumerable<TEntity> entity, string dbName, string collectionName);
        bool Remove(IMongoQuery query, string dbName, string collectionName);
        bool Exists(Expression<Func<TEntity, bool>> exp, string dbName, string collectionName);
        long Count(Expression<Func<TEntity, bool>> exp, string dbName, string collectionName);
        long Count(IMongoQuery query, string dbName, string collectionName);
        void Update(IMongoQuery query, IMongoUpdate update, string dbName, string collectionName);
        void Update(IMongoQuery query, IMongoUpdate update, WriteConcern w, string db, string tableName);
        
        #endregion
    }
}
